package com.zhenmaitang.clinic_sys.security;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhenmaitang.clinic_sys.util.ApiResponse;
import com.zhenmaitang.clinic_sys.service.DataScopeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List;

/**
 * 数据权限拦截器
 * 用于拦截请求并进行数据权限控制
 */
@Component
public class DataScopeInterceptor implements HandlerInterceptor {

    @Autowired
    private DataScopeService dataScopeService;
    
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 如果不是处理方法，则直接放行
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();

        // 检查是否有数据权限注解
        HasDataPermission hasDataPermission = method.getAnnotation(HasDataPermission.class);
        if (hasDataPermission == null) {
            // 如果方法上没有注解，则检查类上是否有注解
            hasDataPermission = handlerMethod.getBeanType().getAnnotation(HasDataPermission.class);
        }

        // 如果没有数据权限注解，则直接放行
        if (hasDataPermission == null) {
            return true;
        }

        // 获取当前用户ID
        Integer userId = getCurrentUserId();
        if (userId == null) {
            handleDataPermissionDenied(response, "未登录或登录已过期");
            return false;
        }

        // 获取请求中的数据ID参数
        String dataIdParam = request.getParameter("dataId");
        if (dataIdParam == null || dataIdParam.isEmpty()) {
            // 尝试从路径变量中获取数据ID
            String requestURI = request.getRequestURI();
            String[] pathParts = requestURI.split("/");
            if (pathParts.length > 0) {
                try {
                    dataIdParam = pathParts[pathParts.length - 1];
                    Long.parseLong(dataIdParam); // 验证是否为数字
                } catch (NumberFormatException e) {
                    dataIdParam = null;
                }
            }
        }

        // 如果没有数据ID参数，则检查是否需要数据ID
        if ((dataIdParam == null || dataIdParam.isEmpty()) && hasDataPermission.requireDataId()) {
            handleDataPermissionDenied(response, "缺少数据ID参数");
            return false;
        }

        // 如果有数据ID参数，则检查数据权限
        if (dataIdParam != null && !dataIdParam.isEmpty()) {
            try {
                Integer dataId = Integer.parseInt(dataIdParam);
                String resource = hasDataPermission.resource();
                
                // 检查用户是否有指定资源的数据权限
                boolean hasPermission = dataScopeService.hasDataPermission(userId, resource, dataId);
                if (!hasPermission) {
                    handleDataPermissionDenied(response, "没有权限访问此数据");
                    return false;
                }
            } catch (NumberFormatException e) {
                handleDataPermissionDenied(response, "数据ID格式错误");
                return false;
            }
        } else if (!hasDataPermission.requireDataId()) {
            // 如果不需要数据ID，则检查用户是否有指定资源的任何数据权限
            String resource = hasDataPermission.resource();
            List<Integer> dataScope = dataScopeService.getUserDataScope(userId, resource);
            
            // 如果dataScope为null，表示有全部权限；如果为空列表，表示没有任何权限
            if (dataScope != null && dataScope.isEmpty()) {
                handleDataPermissionDenied(response, "没有权限访问此类数据");
                return false;
            }
        }

        return true;
    }

    /**
     * 获取当前登录用户ID
     */
    private Integer getCurrentUserId() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated()) {
            return null;
        }
        
        Object principal = authentication.getPrincipal();
        if (principal instanceof CustomUserDetails) {
            return ((CustomUserDetails) principal).getUserId();
        }
        
        return null;
    }

    /**
     * 处理数据权限不足的情况
     */
    private void handleDataPermissionDenied(HttpServletResponse response, String message) throws IOException {
        response.setStatus(HttpServletResponse.SC_FORBIDDEN);
        response.setContentType("application/json;charset=UTF-8");
        
        ApiResponse<String> apiResponse = ApiResponse.error("数据权限不足：" + message);
        String jsonResponse = objectMapper.writeValueAsString(apiResponse);
        
        response.getWriter().write(jsonResponse);
    }
}